/* Autostop
*
* Copyright (c) Maciej Gajewski, Grzegorz Latarowski
* http://code.google.com/p/autostop-automaty-drogowe
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
*/

#include <stdio.h>

#include <QCoreApplication>
#include <QDataStream>

#include "camera.h"
#include "gnetudp.h"
#include "gexception.h"

// types
#define TYPE_Y			0
#define TYPE_SEGMENTED	1
#define TYPE_JPEG		2	

// -------------------------------------
void usage()
{
	printf(
		"Usage: teststreamer <type> <address> <port>\n"
		"      type: y - grayscale (y-channel), s - segmented, j - jpg2k\n"
		);
}

// -------------------------------------
int main( int argc, char** argv )
{

	QCoreApplication app( argc, argv );
	int type;
	
	// get address
	if ( argc < 4 )
	{
		usage();
		return 1;
	}
	
	// get type
	switch( argv[1][0] )
	{
		case 's':
			type = TYPE_SEGMENTED;
			break;
		case 'y':
			type = TYPE_Y;
			break;
		case 'j':
			type = TYPE_JPEG;
			break;
			
		default:
			usage();
			return 1;
			
	}
	
	
	// read address
	QHostAddress address;
	if ( ! address.setAddress( argv[2] ) )
	{
		printf("invalid address: %s\n", argv[1] );
		return 2;
	}
	
	// get port
	int port = -1;
	port = QString( argv[3] ).toInt();
	if ( port < 0 )
	{
		printf("invalid port: %s\n", argv[2] );
		return 3;
	}
	
	GUdpSender sender;
	
	// init camera
	if ( camera_init() != CAMERA_OK )
	{
		printf("can not initialize camera: %s\n", camera_error_message() );
		return 1;
	}
	
	int w = camera_image_width();
	int h = camera_image_height();
	
	// reduce by 8 in segmented mode
	if ( type == TYPE_SEGMENTED )
	{
		w /= 8;
		h /= 8;
	}
	
	QByteArray image;
	image.resize( w * h );
	
	// main loop
	forever
	{
		// get image
		uint64_t timestamp;
		
		switch ( type )
		{
			// grayscale
			case TYPE_Y:
				if ( camera_get_image( (uint8_t*)image.data(), image.size(), &timestamp ) != CAMERA_OK )
				{
					printf("Error geting image: %s\n", camera_error_message() );
					return 2;
				}
				break;
				
			// segmented
			case TYPE_SEGMENTED:
				if ( camera_get_segmented_image( (uint8_t*)image.data(), image.size(), &timestamp ) != CAMERA_OK )
				{
					printf("Error geting setgmented image: %s\n", camera_error_message() );
					return 2;
				}
				// wait 50ms before reading next one
				usleep( 50000);
				break;
				
			// grayscale
			case TYPE_JPEG:
			{
				size_t actual_size = 0;
				image.resize( w * h ); // some guassed upper band
				
				int errorcode;
				if ( ( errorcode = camera_get_jpeg( (uint8_t*)image.data(), image.size(), &actual_size, NULL ) ) != CAMERA_OK )
				{
					printf("Error geting jpeg: %s\n", camera_error_message() );
					if ( errorcode == CAMERA_SMALLBUFFER )
					{
						printf("buffer: current size: %d, required: %d (%dx%d)\n", image.size(), actual_size, w, h );
					}
					return 2;
				}
				image.resize( actual_size );
				break;
			}
			
			// other
			default:
				;
		}
		
		// assembly packet
		QByteArray packet;
		QDataStream stream( & packet, QIODevice::WriteOnly );
		
		int format = (type == TYPE_JPEG) ? int(1) : int(0); // format: 0 - raw grayscale, 1 - jpeg
		stream << w;
		stream << h;
		stream << format;
		stream << image;
		// send image
		try
		{
			sender.sendSync( packet, address, port );
		}
		catch( const GException& e )
		{
			printf("Exception: %s\n", qPrintable(e.getMessage()) );
			return 4;
		}
	}
	
	return 0;
	
}

// eof 

